package com.fengxing.ams.web.facade;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.fengxing.ams.pub.manager.intf.IConfigManager;
import com.fengxing.ams.pub.persistence.DynamicSpecifications;
import com.fengxing.ams.pub.persistence.SearchFilter;
import com.fengxing.ams.pub.persistence.SearchFilter.Operator;
import com.fengxing.ams.web.action.view.EnrollQueryVO;
import com.fengxing.ams.web.action.view.EnrollScoreQueryVO;
import com.fengxing.ams.web.action.view.EnrollmentScoreEntryVO;
import com.fengxing.ams.web.facade.intf.IEnrollmentFacade;
import com.fengxing.ams.web.facade.mouble.enrollment.IMajorEnrollmentDAO;
import com.fengxing.ams.web.facade.mouble.enrollment.MajorEnrollmentVO;

@Component
@Transactional
public class EnrollmentFacade implements IEnrollmentFacade {

	@Autowired
	IMajorEnrollmentDAO majorEnrollmentDAO;
	@Autowired
	IConfigManager configManager;
	
	@Override
	public Page<MajorEnrollmentVO> queryEnrollmentPage(EnrollQueryVO queryVO) {
		if (queryVO == null) {
			Sort sort = new Sort(Sort.Direction.DESC, new String[]{"year", "avgScore"});
			PageRequest pr = new PageRequest(0, 20, sort );
			Page<MajorEnrollmentVO> page = majorEnrollmentDAO.findAll(pr);
			return page;
		}
		
		Sort sort = null;
		List<SearchFilter> searchFilterList = new ArrayList<SearchFilter>();
		SearchFilter filter = null;
		
		String major_ids = queryVO.getMajor_ids();
		if (StringUtils.isNotBlank(major_ids)) {
			String[] major_idArr = major_ids.split(",");
			Integer[] major_idIntArr = new Integer[major_idArr.length];
			for (int i = 0; i < major_idArr.length; i++) {
				major_idIntArr[i] = Integer.valueOf(major_idArr[i]);
			}
			filter  = new SearchFilter("major_id", Operator.IN, major_idIntArr);
			searchFilterList.add(filter);
		}
		
		String description_id = queryVO.getDescription_ids();
		if (StringUtils.isNotBlank(description_id)) {
			String[] description_ids = description_id.split(",");
			Integer[] descInts = new Integer[description_ids.length];
			for (int i = 0; i < description_ids.length; i++) {
				descInts[i] = Integer.valueOf(description_ids[i]);
			}
			filter  = new SearchFilter("description_id", Operator.IN, descInts);
			searchFilterList.add(filter);
		}
		
		String college_id = queryVO.getCollege_ids();
		if (StringUtils.isNotBlank(college_id)) {
			String[] college_ids = college_id.split(",");
			Integer[] collegeInts = new Integer[college_ids.length];
			for (int i = 0; i < college_ids.length; i++) {
				collegeInts[i] = Integer.valueOf(college_ids[i]);
			}
			filter  = new SearchFilter("college_id", Operator.IN, collegeInts);
			searchFilterList.add(filter);
		}
		
		String subject = queryVO.getSubject();
		if (StringUtils.isNotBlank(subject)) {
			String[] subjects = subject.split(",");
			filter  = new SearchFilter("subject", Operator.IN, subjects);
			searchFilterList.add(filter);
		}
		
		String batch = queryVO.getBatch();
		if (StringUtils.isNotBlank(batch)) {
			String[] batchs = batch.split(",");
			filter  = new SearchFilter("batch", Operator.IN, batchs);
			searchFilterList.add(filter);
		}
		
		Integer year = queryVO.getYear();
		if (year != null) {
			filter  = new SearchFilter("year", Operator.EQ, year, null);
			searchFilterList.add(filter);
		}
		
		if (queryVO.getOrder() == null || queryVO.getOrder() == 1) {
			sort = new Sort(Sort.Direction.DESC, new String[]{"year", "avgScore"});
		} else if (queryVO.getOrder() == 2) {
			sort = new Sort(Sort.Direction.DESC, new String[]{"year", "maxScore"});
		} else if (queryVO.getOrder() == 3) {
			sort = new Sort(Sort.Direction.DESC, new String[]{"year", "minScore"});
		} else if (queryVO.getOrder() == 4) {
			sort = new Sort(Sort.Direction.DESC, "year").and(new Sort(Sort.Direction.ASC, "minRanking"));
		} else if (queryVO.getOrder() == 5) {
			sort = new Sort(Sort.Direction.DESC, new String[]{"year", "enrolled"});
		}
//		sort.and(new Sort(Sort.Direction.DESC, new String[]{"college_id", "major_id"}));
		PageRequest pr = new PageRequest(queryVO.getPage() != null ? queryVO.getPage() : 0, 20, sort );
		
		Specification<MajorEnrollmentVO> spec = DynamicSpecifications.bySearchFilter(
				searchFilterList, MajorEnrollmentVO.class);
		return this.majorEnrollmentDAO.findAll(spec, pr);
	}
		

	@Override
	public List<MajorEnrollmentVO> queryEnrollmentGraph(EnrollQueryVO queryVO) {
		return this.majorEnrollmentDAO.queryEnrollmentGraph(queryVO.getBatch(), queryVO.getSubject(), queryVO.getCollege_id(), queryVO.getMajor_id());
	}


	@Override
	public Page<MajorEnrollmentVO> queryEnrollment(EnrollQueryVO queryVO,
			boolean isRelease) {
		if (queryVO == null) {
			Sort sort = new Sort(Sort.Direction.DESC, new String[]{"year", "avgScore"});
			PageRequest pr = new PageRequest(0, 20, sort );
			Page<MajorEnrollmentVO> page = majorEnrollmentDAO.findAll(pr);
			return page;
		}
		return null;
	}


	@Override
	public List<MajorEnrollmentVO> queryEnrollmentByStdScorePage(
			EnrollScoreQueryVO queryVO) {
		Integer weightThreshold = Integer.valueOf(this.configManager.getProperty("weight_threshold", "50"));
		return this.majorEnrollmentDAO.queryEnrollByScorePage(queryVO.getBatch(), queryVO.getSubject(), queryVO.getScore() - queryVO.getRange(), 
				queryVO.getScore() + queryVO.getRange(), weightThreshold, queryVO.getPage() * 20, 20);
	}


	@Override
	public int queryEnrollmentByStdScoreTotal(EnrollScoreQueryVO queryVO) {
		Integer weightThreshold = Integer.valueOf(this.configManager.getProperty("weight_threshold", "50"));
		return this.majorEnrollmentDAO.countEnrollByScorePage(queryVO.getBatch(), queryVO.getSubject(), queryVO.getScore() - queryVO.getRange(), 
				queryVO.getScore() + queryVO.getRange(), weightThreshold);
	}


}
